package com.yzd.netmonitor.util;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;

public class Parser {
	
	public enum DateType {
		Full,
		FullHour,
		FullMin,
		Short,
		JDDay,
		Day,
		Month,
		Time,
		PlanTime,
		JDFull,
		SougouShort,
		Week;
		
		public static SimpleDateFormat formatFromDateType (DateType type) {
			
			switch (type) {
			case Full: return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			case FullHour: return new SimpleDateFormat("yyyy-MM-dd HH:00:00");
			case FullMin: return new SimpleDateFormat("yyyy-MM-dd HH:mm:00");
			
			case Short: return new SimpleDateFormat("M月d日 HH:mm");
			case Day: return new SimpleDateFormat("yyyy-MM-dd");
			case Month: return new SimpleDateFormat("yyyy-MM");
			case Time: return new SimpleDateFormat("HH:mm:ss");
			case PlanTime: return new SimpleDateFormat("HH:mm");
			
			case JDFull: return new SimpleDateFormat("yyyyMMddHHmmss");
			case JDDay: return new SimpleDateFormat("yyyyMMdd");
			
			case SougouShort : return new SimpleDateFormat("MM月dd日");  
			case Week:return new SimpleDateFormat("E");

			default:
				break;
			}
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			
		}
	}
	
	public static int defaultInt = -99999999;
	
	//int float section	
	public static int getInt (Object obj, int defaultValue) {
		if ( obj != null ) {
			try {
				if (obj instanceof Integer) {
					return ((Integer)obj).intValue();
				}
				if (obj instanceof String) {
					String str = (String)obj;
					if ( str != null && !str.equals("") && str.matches("\\d+")) {
						return Integer.parseInt(str);
					}
				}
				if (obj instanceof Long) {
					return (int)((Long)obj).longValue();
				}
				if (obj instanceof Float) {
					return (int)((Float)obj).floatValue();
				}
				if (obj instanceof Double) {
					return (int)((Double)obj).doubleValue();
				}
				if (obj instanceof BigDecimal) {
					return (int)((BigDecimal)obj).intValue();
				}	
			} catch (Exception e) {
				return defaultValue;
			}
		}
		return defaultValue;
	}
	
	public static int getInt (Object obj) {
		return getInt(obj, defaultInt);
	}
	
	public static int getInt (HashMap<?, ?> set, String key) {
		if (key == null) {
			return defaultInt;
		}
		Object obj = set.get(key);
		return getInt(obj);
	}
	
	public static int getInt (HashMap<?, ?> set, String key, int defaultValue) {
		int value = getInt(set, key);
		return value == defaultInt? defaultValue: value;
	}
	
	public static float getFloat (Object obj) {
		try {
			if ( obj != null ) {
				if (obj instanceof Integer) {
					return ((Integer)obj).intValue();
				}
				if (obj instanceof String) {
					if (Parser.length((String)obj) == 0) {
						return 0;
					}
					return Float.parseFloat((String)obj);
				}
				if (obj instanceof Long) {
					return ((Long)obj).longValue();
				}
				if (obj instanceof Float) {
					return ((Float)obj).floatValue();
				}
				if (obj instanceof Double) {
					return (float)((Double)obj).doubleValue();
				}
				if (obj instanceof BigDecimal) {
					return ((BigDecimal)obj).floatValue();
				}
				return 0;
			}
		} catch (Exception e) {
		}
		return defaultInt;
	}
	
	public static float getFloat (HashMap<?, ?> set, String key) {
		if (key == null) {
			return defaultInt;
		}
		Object obj = set.get(key);
		return getFloat(obj);
	}

	public static float getFloat (HashMap<?, ?> set, String key, int defaultValue) {
		float value = getFloat(set, key);
		return value == defaultInt? defaultValue: value;
	}
	
	public static double getDouble (Object obj) {
		return getDouble(obj, defaultInt);
	}
	
	public static double getDouble (Object obj, double defaultValue) {
		if ( obj != null ) {
			if (obj instanceof Integer) {
				return ((Integer)obj).intValue();
			}
			if (obj instanceof String) {
				if (Parser.length((String)obj) == 0) {
					return 0;
				}
				return Float.parseFloat((String)obj);
			}
			if (obj instanceof Long) {
				return ((Long)obj).longValue();
			}
			if (obj instanceof Float) {
				return ((Float)obj).floatValue();
			}
			if (obj instanceof Double) {
				return ((Double)obj).doubleValue();
			}
			if (obj instanceof BigDecimal) {
				return ((BigDecimal)obj).doubleValue();
			}
			return 0;
		} else {
			return defaultValue;
		}
	}
	
	public static double getDouble (HashMap<?, ?> set, String key) {
		return getDouble(set, key, defaultInt);
	}
	
	public static double getDouble (HashMap<?, ?> set, String key, int defaultValue) {
		if (key == null) {
			return defaultInt;
		}
		Object obj = set.get(key);
		return getDouble(obj, defaultValue);
	}
	
	public static long getLong (Object obj, int defaultValue) {
		if ( obj != null ) {
			try {
				if (obj instanceof Integer) {
					return ((Integer)obj).intValue();
				}
				if (obj instanceof String) {
					String str = (String)obj;
					if ( str != null && !str.equals("") && str.matches("\\d+")) {
						return Long.parseLong(str);
					}
				}
				if (obj instanceof Long) {
					return ((Long)obj).longValue();
				}
				if (obj instanceof Float) {
					return (long)((Float)obj).floatValue();
				}
				if (obj instanceof Double) {
					return (long)((Double)obj).doubleValue();
				}
				if (obj instanceof BigDecimal) {
					return (long)((BigDecimal)obj).intValue();
				}	
			} catch (Exception e) {
				return defaultValue;
			}
		}
		return defaultValue;
	}
	
	public static long getLong (Object obj) {
		return getLong(obj, defaultInt);
	}
	
	
	//string section
	public static String getString (int a) {
		return a + "";
	}
	
	public static String getString (HashMap<?, ?> set, String key) {
		if (key == null) {
			return null;
		}
		Object obj = set.get(key);
		if ( obj != null )
			return (obj instanceof String)? (String)obj: obj.toString();
		return null;
	}
	
	public static String getString (Date date) {
		return getString(date, DateType.Full);
	}
	
	public static String getString (Date date, DateType type) {
		if ( date != null )
			return DateType.formatFromDateType(type).format(date);
		return null;
	}

	public static int length (String string) {
		return string == null? 0: string.length();
	}
	
	public static String replace(String strSource, String strFrom, String strTo) {
		if (strSource == null) { 
			return null;
		}
		
		int i = 0;
		if ((i = strSource.indexOf(strFrom, i)) >= 0) {
			char[] cSrc = strSource.toCharArray();
			char[] cTo = strTo.toCharArray();
			int len = strFrom.length();
			StringBuffer buf = new StringBuffer(cSrc.length);
			buf.append(cSrc, 0, i).append(cTo);
			i += len;
			int j = i;
			while ((i = strSource.indexOf(strFrom, i)) > 0) {
				buf.append(cSrc, j, i - j).append(cTo);
				i += len;
				j = i;
			}
			buf.append(cSrc, j, cSrc.length - j);
			return buf.toString(); 
	    } 
	    return strSource;
	}
	 
	public static String urlEncode (String source) {
		return urlEncode(source, "utf-8");
	}
	
	public static String urlEncode (String source, String enc) {
		if (source == null || enc == null) {
			return source;
		}
		String encode = null;
		try {
			encode = URLEncoder.encode(source, enc);
			encode = replace(encode, "+", "%20");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} finally {
			
		}
		return encode;
	}
	
	public static String urlDecode (String source) {
		return urlDecode(source, "utf-8");
	}
	
	public static String urlDecode (String source, String enc) {
		String decode = null;
		try {
			decode = URLDecoder.decode(source, enc);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} finally {
			
		}
		return decode;
	}
	
	/**
	 * 检查是否包含某个子项，如果父串为 null/""/"all" 都认为是全部
	 * */
	public static boolean containElementIgnoreCase (String parent, Object sub) {
		if (sub == null || sub.toString() == null) {
			return false;
		}
		if(sub instanceof String){
			if("".equals(((String) sub).trim())){
				return false;
			}
		}
		if (parent == null || parent.equals("") || parent.equalsIgnoreCase("all") || sub.equals("all") || Parser.getInt(sub) == 0) {
			return true;
		}
		
		return ( "," + parent.toLowerCase() + ",")
				.indexOf("," + sub.toString().toLowerCase() + ",") > -1;
	}
	
	/**
	 * 全角半角转换
	 * */
	public static String qj2bj(String src) {
        if (src == null) {  
            return src;  
        }
        
		//char DBC_CHAR_START = 33; // 半角!
		
	    /**
	     * ASCII表中可见字符到~结束，偏移位值为126(Decimal)
	     */
		//char DBC_CHAR_END = 126; // 半角~
		
	    /**
	     * 全角对应于ASCII表的可见字符从！开始，偏移值为65281
	     */
		char SBC_CHAR_START = 65281; // 全角！ 
		  
	    /**
	     * 全角对应于ASCII表的可见字符到～结束，偏移值为65374 
	     */ 
		char SBC_CHAR_END = 65374; // 全角～
		  
	    /** 
	     * ASCII表中除空格外的可见字符与对应的全角字符的相对偏移
	     */
		int CONVERT_STEP = 65248; // 全角半角转换间隔
		
	    /** 
	     * 全角空格的值，它没有遵从与ASCII的相对偏移，必须单独处理 
	     */
		char SBC_SPACE = 12288; // 全角空格 12288
		
	    /** 
	     * 半角空格的值，在ASCII中为32(Decimal) 
	     */
		char DBC_SPACE = ' '; // 半角空格 

        StringBuilder buf = new StringBuilder(src.length());
        char[] ca = src.toCharArray();
        for (int i = 0; i < src.length(); i++) {
            if (ca[i] >= SBC_CHAR_START && ca[i] <= SBC_CHAR_END) { // 如果位于全角！到全角～区间内  
                buf.append((char) (ca[i] - CONVERT_STEP));
            } else if (ca[i] == SBC_SPACE) { // 如果是全角空格
                buf.append(DBC_SPACE);
            } else { // 不处理全角空格，全角！到全角～区间外的字符
                buf.append(ca[i]);
            }
        }
        return buf.toString();  
	}
	
	
	//date section
 	public static Date getDate (HashMap<?, ?> set, String key) {
		return getDate(set, key, DateType.Full);
	}

	public static Date getDate (HashMap<?, ?> set, String key, DateType type) {
		if (key == null) {
			return null;
		}
		Object obj = set.get(key);
		if ( obj != null )
			if (obj instanceof String) {
				try {
					return DateType.formatFromDateType(type).parse((String)obj);
				} catch (ParseException e) {
					e.printStackTrace();
				}
			} else if (obj instanceof Date) {
				return (Date)obj;
			} else if (obj instanceof Long) {
				return new Date(((Long)obj).longValue());
			}
		return null;
	}
	
	public static Date getDate (String str) {
		Date retDate = getDate(str, DateType.Full);
		if (retDate == null) {
			return getDate(str, DateType.Day);
		} else {
			return retDate;
		}
	}
	
	public static Date getDateByMonths(int months){
		Calendar calendar = Calendar.getInstance();
		  calendar.add(Calendar.MONTH, months);
		  calendar.get(Calendar.YEAR);
		  calendar.get(Calendar.MONTH );
		  calendar.get(Calendar.DAY_OF_MONTH);  
		  return calendar.getTime();
	}
	
	public static Date getDate (String str, DateType type) {
		if (str == null) {
			return null;
		}
		try {
			return DateType.formatFromDateType(type).parse(str);
		} catch (ParseException e) {
			System.err.print(e.getMessage());
		}

		return null;
	}
	
	public static Date newDate (int year, int month, int day, int hour, int min, int sec) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(year, month - 1, day, hour, min, sec);
		return calendar.getTime();
	}
	
	
	//double section
	/**
	 * 截取小数位数
	 * */
	public static float roundChange(float a ,int b) {
		if(b < 0) return a;
		int k = 1;
		for(int i = 0; i < b; i++) {
			k = k * 10;
		}
		return ((float)Math.round(a*k))/k;
	}
	
	
	//boolean section
	public static boolean getBool (String str) {
		if ( str != null && !str.equals("") ) {
			if (str.compareToIgnoreCase("yes") == 0 
				|| str.compareToIgnoreCase("true") == 0) {
				return true;
			}
			if (str.compareToIgnoreCase("no") == 0 
				|| str.compareToIgnoreCase("false") == 0) {
				return false;
			}
			return getInt(str)>0;
		}
		return false;
	}
	
	public static Boolean getBoolean (HashMap<?, ?> set, String key) {
		if (key == null) {
			return null;
		}
		Object obj = set.get(key);
		if ( obj != null ) {
			if (obj instanceof Integer) {
				return Boolean.valueOf(((Integer)obj).intValue() > 0);
			}
			if (obj instanceof String) {
				return Boolean.valueOf(getBool((String)obj));
			}
			if (obj instanceof Long) {
				return Boolean.valueOf(((Long)obj).longValue() > 0);
			}
			if (obj instanceof Float) {
				return Boolean.valueOf(((Float)obj).floatValue() > 0);
			}
			if (obj instanceof Double) {
				return Boolean.valueOf((int)((Double)obj).doubleValue() > 0);
			}
			if (obj instanceof Boolean) {
				return (Boolean)obj;
			}
		}
		return null;
	}
	
	/**
	 * 传入的时间+N分钟或者-N分钟
	 * @param date
	 * @param time 整数代表加 负数代表减
	 * @return
	 */
	public static Date addOrDelMINUTEDate(Date date,int time){
		if(date == null)
			return null;
		Calendar rightNow = Calendar.getInstance();
		rightNow.setTime(date);
		rightNow.add(Calendar.MINUTE, time);
		return rightNow.getTime();
	}
	
	public static boolean getBool (HashMap<?, ?> set, String key) {
		Boolean booleanValue = getBoolean(set, key);
		if (booleanValue == null) {
			return false;
		} else {
			return booleanValue.booleanValue();
		}
	}
	
	
	//until section
	/**
	 * 字符串为空或者all的话对应{0}
	 * */
	public static ArrayList<Integer> stringToIntArray (String input) {
		ArrayList<Integer> array = new ArrayList<Integer>();
		if (input == null || input.equalsIgnoreCase("all")) {
			array.add(0);
		} else {
			String[] ids = input.split(",");
			for (String string : ids) {
				array.add(Parser.getInt(string));
			}
		}
		return array;
	}
	
	public static HashMap<String, Object> trimHashMap (HashMap<String, Object> set) {
		Iterator<Entry<String, Object>> it =  set.entrySet().iterator();
        while( it.hasNext() ) {
        	Entry<String, Object> obj = it.next();
        	Object value = obj.getValue();
        	if (value == null) {
        		it.remove();
        		continue;
        	}
        	if (value instanceof Integer) {
        		if ( ((Integer)value).intValue() == defaultInt ) {
					it.remove();
				}
			}
         }
         return set;
	}
	
	/**
	 * 比较时间大小
	 * @param startTime
	 * @param endTime
	 * @param type
	 * @return
	 */
	public static boolean compareDate (Date time1, Date time2, DateType type) {
		return compareDate(time1,time2,type,true);
	}
	
	/**
	 * 比较两个时间的大小 ，tag=false的时候包涵 相等
	 * @param time1
	 * @param time2
	 * @param type
	 * @param tag
	 * @return
	 */
	public static boolean compareDate (Date time1, Date time2, DateType type,boolean tag) {
		if (time1 == null || time2 ==null) {
			return false;
		}
		Date stime = Parser.getDate(Parser.getString(time1,type),type);
		Date etime = Parser.getDate(Parser.getString(time2,type),type);
		if(tag){
			if(stime.getTime() > etime.getTime()){
				return true;
			}
		} else {
			if(stime.getTime() >= etime.getTime()){
				return true;
			}
		}
		return false;
	}
	
	
	public static void main (String[] args) {
//		System.out.println(getInt("1.1"));
//		System.out.println(getBool("true"));
//		System.out.println(roundChange(1.99533f, 2));
//		System.out.println(getFloat(""));
//		System.out.println(addOrDelMINUTEDate(new Date(System.currentTimeMillis()),-30));
		System.out.println(compareDate(Parser.getDate("2015-07-02 11:00:00"),null,DateType.Time));
	}
}
